// 联合类型（并集） ｜  按位或  联合类型的数据，只能符合一个类型
// 交叉类型 （交集） & 按位与 交叉类型的数据可以赋值给之前任意一个类型
interface Person1 {
  handsome: string;
}
interface Person2 {
  high: string;
}
type Person3 = Person1 & Person2;
type Person9 = Person1 | Person2;
// let person:Person1 | Person2 = {
//     high:'高'
// }
// 交叉类型 同时是两个类型的子类型， 最终的结果可以赋予给任何的一个类型
// 子类型可以赋予给 父类型 （子类型的结构要包含父类型的结构）
// let person1:Person1 & Person2 = {
//     handsome:'帅',
//     high:'高',
// }
// 子类型可以赋予给 父类型 （子类型的结构要包含父类型的结构  将一个值赋予给另一个值，有类型兼容性，可以将子类型赋予给父类型）
// let ooo = {
//   handsome: "帅",
//   high: "高",
// };
// let person2: Person1 = ooo;

/* 
// 如果相同字段，类型不相同 &集后的结果是never  meta: {n: never, b: number}....................................
interface Person1 {
  handsome: string;
  gender: number;
  meta: {
    // 如果相同字段，类型不相同 &集后的结果是never

    n: number;
  };
}
interface Person2 {
  high: string;
  gender: string;
  meta: {
    // 如果相同字段，类型不相同 &集后的结果是never  meta: {n: never, b: number}
    n: string;
    // 如果不相同字段， &集后的结果是 meta: {n: never, b: number}
    b: number;
  };
}


type Person3 = Person1 & Person2;
type Person9 = Person1 | Person2;
type IGender = Person3["meta"]["n"]; // 如果相同字段，类型不相同 &集后的结果是never
 */

// 更新类型..................................................................
type IUnion<T> = T | string | number;
// IUnion; ====> string | number | T
// 未加& {} union; ====> IUnion<boolean>
// 加了& {} union; ====> string | number | boolean
let union: IUnion<boolean> & {} = true;

// let person1:Person1 =person
// let person2:Person2 =person
// 快速扩展属性
let obj = { name: "jw", age: 30 };
let person: { name: string; age: number; address: string } =
  obj as typeof obj & { address: string };
function merge<T extends object, K extends object>(o1: T, o2: K) {
  return { ...o1, ...o2 };
}
let result = merge({ name: "abc" }, { name: 123 });
// result.name
// 交叉类型和联合类型的区别， 平时我门使用的交叉类型场景还是很多的
export { };
